package vsvm.data.source;

import java.util.ArrayList;

import vsvm.data.model.AbstractAttribute;
import vsvm.data.model.AbstractDataModel;
import vsvm.data.model.CategorialAttribute;
import vsvm.data.model.NumericAttribute;
import vsvm.gui.Environment;
import vsvm.gui.forms.ConfigureArffDataSource;

public class ArffDataSource extends FileDataSource {
	private static final long serialVersionUID = 100L;

	@Override
	public void fill(AbstractDataModel model, AbstractAttribute classAttr) throws Exception {
		if (!opened) return;
		
		if (attributes == null) {
			readAttributes();
		}

		String line;
			
		try {
			model.setAttributes(attributes);
			ArrayList<double[]> data = new ArrayList<double[]>();
			//ArrayList<Double> y = new ArrayList<Double>();
			double[] vec;
			
			while ( (line =  reader.readLine()) != null) {
				String[] vals = line.split(",");
				if (vals.length != attributes.size()) {
					
				} else {
					vec = new double[vals.length];
					for (int i = 0, j = 0; i < vals.length; i++) {
						//if (attributes.get(i) != classAttr)
							vec[j++] = attributes.get(i).toDouble(vals[i]);
						//else
							//y.add(attributes.get(i).toDouble(vals[i]));
							
					}
					data.add(vec);					
				}				
			}
			
			model.setData(data, model.getAtttributeIndex(classAttr));
		} catch (Exception e) {
			throw e;
		}		
	}

	@Override
	public ArrayList<AbstractAttribute> readAttributes() {
		if (!opened) return null;

		attributes = new ArrayList<AbstractAttribute>();
		try {
			while (true) {
				String line = reader.readLine();
				if (line == null) break;
				if (line.startsWith("%"))
					continue;
				if (line.toLowerCase().startsWith("@relation"))
					continue;
				if (line.toLowerCase().startsWith("@attribute")) {
					String[] s = line.split(" ");
					if (s.length < 3) continue;
					if (s[2].toLowerCase().equals("numeric") || s[2].toLowerCase().equals("real")) {
						attributes.add(new NumericAttribute(s[1]));
					} else 
						attributes.add(new CategorialAttribute(s[1]));
					continue;
				}
				break;				
			}
		} catch (Exception e) {
			
		}

		return attributes;
	}

	public void configure() {
		ConfigureArffDataSource d = new ConfigureArffDataSource(Environment.getEnvironment().getMainFrame(), this);
		d.setVisible(true);		
	}

	public String getQuickInfo() {
		StringBuilder sb = new StringBuilder();
		sb.append("Arff file data source" + Environment.newline);
		sb.append("File name:  " + filename + Environment.newline);
		return sb.toString();
	}

}
